#if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.
#if UNITY_EDITOR
using AudioStudio;
using System;
using System.Collections.Generic;
using UnityEngine.UI;
/// <summary>
///     @brief This class is used to perform DragAndDrop operations from the AkWwisePicker to any GameObject.
///     We found out that DragAndDrop operations in Unity do not transfer components, but only scripts. This
///     prevented us to set the name and ID of our components before performing the drag and drop. To fix this,
///     the DragAndDrop operation always transfers a AkDragDropHelper component that gets instantiated on the
///     target GameObject. On its Awake() call, it will parse the DragAndDrop structure, which contains
///     all necessary information to instantiate the correct component, with the correct information
/// </summary>
[UnityEngine.ExecuteInEditMode]
public class AkDragDropHelper : UnityEngine.MonoBehaviour
{
	public static string DragDropIdentifier = "AKWwiseDDInfo";

	private void Awake()
	{
		UnityEngine.GUIUtility.hotControl = 0;

		var reference = UnityEditor.DragAndDrop.GetGenericData(DragDropIdentifier) as WwiseObjectReference;
		if (reference == null)
			return;
        switch (reference.WwiseObjectType)
        {
            case WwiseObjectType.AuxBus:
                var akEnvironments = gameObject.GetComponents<AkEnvironment>();
                foreach (var environment in akEnvironments)
                {
                    Guid guid = new Guid(environment.data.valueGuid);
                    if (guid.Equals(reference.Guid))
                        return;
                }

                var AkEnvironment = UnityEditor.Undo.AddComponent<AkEnvironment>(gameObject);
                if (AkEnvironment != null)
                {
                    AkEnvironment.data.Id = reference.Id;
                    AkEnvironment.data.Name = reference.ObjectName;
                    CopyGuid(reference.Guid.ToByteArray(), AkEnvironment.data.valueGuid);
                }
                break;

            case WwiseObjectType.Event:
                AddEvent(reference);
                break;

            case WwiseObjectType.Soundbank:
                AddSoundBank(reference);
                break;

            case WwiseObjectType.State:
                AddState(reference);
                break;

            case WwiseObjectType.Switch:
                var AkSwitch = UnityEditor.Undo.AddComponent<AkSwitch>(gameObject);
                if (AkSwitch != null)
                {
                    AkSwitch.data.Id = reference.Id;
                    AkSwitch.data.Name = reference.ObjectName;
                    CopyGuid(reference.Guid.ToByteArray(), AkSwitch.data.valueGuid);
                }
                break;
        }
        DestroyImmediate(reference);
    }

	private void Start()
	{
		// Don't forget to destroy the AkDragDropHelper when we're done!
		DestroyImmediate(this);
	}

    private bool CopyGuid(byte[] from, byte[] to)
    {
        if (from.Length == to.Length)
        {
            from.CopyTo(to, 0);
            return true;
        }
        return false;
    }

    private void AddEvent(WwiseObjectReference reference)
    {
        var bt = gameObject.GetComponent<Button>();
        if (bt != null)
        {
            var bs = UnityEditor.Undo.AddComponent<ButtonSound>(gameObject);
            if (bs != null)
            {
                List<AudioEvent> aelist = new List<AudioEvent>();
                AudioEvent ae = new AudioEvent();
                ae.Name = reference.DisplayName;
                ae.Id = reference.Id;
                CopyGuid(reference.Guid.ToByteArray(), ae.valueGuid);
                aelist.Add(ae);
                bs.audioEvents = aelist.ToArray();
            }
        }
        else
        {
            var tg = gameObject.GetComponent<Toggle>();
            if (tg != null)
            {
                var ts = UnityEditor.Undo.AddComponent<ToggleSound>(gameObject);
                if (ts != null)
                {
                    List<AudioEvent> aelist = new List<AudioEvent>();
                    AudioEvent ae = new AudioEvent();
                    ae.Name = reference.DisplayName;
                    ae.Id = reference.Id;
                    CopyGuid(reference.Guid.ToByteArray(), ae.valueGuid);
                    aelist.Add(ae);
                    ts.toggleaudioEvents = aelist.ToArray();
                }
            }
            else
            {
                var audioinit = gameObject.GetComponent<AudioInit>();
                if (audioinit != null)
                {
                    if (audioinit.events == null)
                    {
                        audioinit.events = new AudioEvent();
                    }
                    audioinit.events.Name = reference.DisplayName;
                    audioinit.events.Id = reference.Id;
                    CopyGuid(reference.Guid.ToByteArray(), audioinit.events.valueGuid);
                }
                else
                {
                    var es = UnityEditor.Undo.AddComponent<EmitterSound>(gameObject);
                    if (es != null)
                    {
                        es.audioevent = new AudioEvent();
                        es.audioevent.Name = reference.DisplayName;
                        es.audioevent.Id = reference.Id;
                        CopyGuid(reference.Guid.ToByteArray(), es.audioevent.valueGuid);
                    }
                }
            }
        }
    }

    private void AddSoundBank(WwiseObjectReference reference)
    {
        var bank = gameObject.GetComponent<SoundBanks>();
        if (bank != null)
        {
            List<SoundBankParam> sbplist = new List<SoundBankParam>();
            for (int i = 0; i < bank.banks.Length; i++)
                sbplist.Add(bank.banks[i]);
            SoundBankParam sbp = new SoundBankParam();
            sbp.bank = new Bank();
            sbp.load = true;
            sbp.unload = true;
            sbp.bank.Id = reference.Id;
            sbp.bank.Name = reference.DisplayName;
            CopyGuid(reference.Guid.ToByteArray(), sbp.bank.valueGuid);
            sbplist.Add(sbp);
            bank.banks = sbplist.ToArray();
        }
        else
        {
            var audioinit = gameObject.GetComponent<AudioInit>();
            if (audioinit != null)
            {
                List<SoundBankParam> sbplist = new List<SoundBankParam>();
                if (audioinit.banks != null)
                {
                    for (int i = 0; i < audioinit.banks.Length; i++)
                        sbplist.Add(audioinit.banks[i]);
                }
                SoundBankParam sbp = new SoundBankParam();
                sbp.bank = new Bank();
                sbp.load = true;
                sbp.unload = false;
                sbp.bank.Id = reference.Id;
                sbp.bank.Name = reference.DisplayName;
                CopyGuid(reference.Guid.ToByteArray(), sbp.bank.valueGuid);
                sbplist.Add(sbp);
                audioinit.banks = sbplist.ToArray();
            }
            else
            {
                bank = UnityEditor.Undo.AddComponent<SoundBanks>(gameObject);
                if (bank != null)
                {
                    List<SoundBankParam> sbplist = new List<SoundBankParam>();
                    SoundBankParam sbp = new SoundBankParam();
                    sbp.bank = new Bank();
                    sbp.load = true;
                    sbp.unload = true;
                    sbp.bank.Id = reference.Id;
                    sbp.bank.Name = reference.DisplayName;
                    CopyGuid(reference.Guid.ToByteArray(), sbp.bank.valueGuid);
                    sbplist.Add(sbp);
                    bank.banks = sbplist.ToArray();
                }
            }
        }
    }

    private void AddState(WwiseObjectReference reference)
    {
        var state = gameObject.GetComponent<SetState>();
        var groupReference = reference as WwiseGroupValueObjectReference;
        if (groupReference && groupReference.GroupObjectReference)
        {
            List<StateParam> splist = new List<StateParam>();
            if (state != null)
            {
                for (int i = 0; i < state.States.Length; i++)
                    splist.Add(state.States[i]);
                StateParam st = new StateParam();
                st.state = new State();
                st.state.Id = groupReference.Id;
                st.state.Name = groupReference.DisplayName;
                CopyGuid(groupReference.Guid.ToByteArray(), st.state.valueGuid);
                st.state.GroupId = groupReference.GroupObjectReference.Id;
                st.state.GroupName = groupReference.GroupObjectReference.DisplayName;
                splist.Add(st);
                state.States = splist.ToArray();
            }
            else
            {
                var audioinit = gameObject.GetComponent<AudioInit>();
                if (audioinit != null)
                {
                    if (audioinit.states == null)
                    {
                        audioinit.states = new State();
                    }
                    audioinit.states.Id = reference.Id;
                    audioinit.states.Name = reference.DisplayName;
                    CopyGuid(reference.Guid.ToByteArray(), audioinit.states.valueGuid);
                }
                else
                {
                    state = UnityEditor.Undo.AddComponent<SetState>(gameObject);
                    if (state != null)
                    {
                        StateParam st = new StateParam();
                        st.state = new State();
                        st.state.Id = groupReference.Id;
                        st.state.Name = groupReference.DisplayName;
                        CopyGuid(groupReference.Guid.ToByteArray(), st.state.valueGuid);
                        st.state.GroupId = groupReference.GroupObjectReference.Id;
                        st.state.GroupName = groupReference.GroupObjectReference.DisplayName;
                        splist.Add(st);
                        state.States = splist.ToArray();
                    }
                }
            }
        }
    }
}
#endif // UNITY_EDITOR
#endif // #if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.